home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / game / wins1726.zip / MISCOVL.C < prev    next >
C/C++ Source or Header  |  1992-06-03  |  34KB  |  1,154 lines

  1. /*
  2.     Overlayed odds and ends that don't fit anywhere else.
  3. */
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <process.h>
  9. #include <dos.h>
  10. #include <stdarg.h>
  11. #include "fractint.h"
  12. #include "fractype.h"
  13. #include "helpdefs.h"
  14.  
  15. /* routines in this module    */
  16.  
  17. void miscovl_overlay(void);
  18. void make_batch_file(void);
  19. void shell_to_dos(void);
  20. void showfreemem(void);
  21. int  select_video_mode(int);
  22.  
  23. #ifdef WINFRACT
  24. #endif
  25. void write_batch_parms(FILE *,char *,int);
  26. static void put_parm(char *parm,...);
  27.  
  28. static void put_parm_line(void);
  29. static int getprec(double,double,double);
  30. static void put_float(int,double,int);
  31. static void put_filename(char *keyword,char *fname);
  32. static void format_item(int choice,char *buf);
  33. static int check_modekey(int curkey,int choice);
  34. static int entcompare(void const *p1,void const *p2);
  35. static void update_fractint_cfg(void);
  36.  
  37. extern int  cpu;        /* cpu type            */
  38. extern int  fpu;        /* fpu type            */
  39. extern int  iit;        /* iit fpu?            */
  40. extern int  video_type;
  41. extern int  askvideo;
  42. extern char overwrite;        /* 1 means ok to overwrite */
  43. extern int  fillcolor;        /* fill color: -1 = normal*/
  44. extern int  inside;        /* inside color: 1=blue     */
  45. extern int  outside;        /* outside color, if set    */
  46. extern double xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners */
  47. extern double param[4];     /* up to four parameters    */
  48. extern int  finattract;     /* finite attractor option  */
  49. extern int  forcesymmetry;
  50. extern int  LogFlag;        /* non-zero if logarithmic palettes */
  51. extern int  rflag, rseed;
  52. extern int  periodicitycheck;
  53. extern int  potflag;        /* continuous potential flag */
  54. extern int  pot16bit;        /* save 16 bit values for continuous potential */
  55. extern double potparam[3];    /* three potential parameters*/
  56. extern int  fractype;        /* if == 0, use Mandelbrot  */
  57. extern unsigned char usemag;
  58. extern long delmin;
  59. extern int  maxit;        /* try this many iterations */
  60. extern int  invert;        /* non-zero if inversion active */
  61. extern double inversion[];
  62. extern int  decomp[];
  63. extern int  distest;        /* non-zero if distance estimator   */
  64. extern int  distestwidth;
  65. extern int  init3d[20];     /* '3d=nn/nn/nn/...' values */
  66. extern char floatflag;        /* floating-point fractals? */
  67. extern int  usr_biomorph;
  68. extern char FormFileName[];    /* file to find (type=)formulas in */
  69. extern char FormName[];     /* Name of the Formula (if not null) */
  70. extern char LFileName[];
  71. extern char LName[];
  72. extern char IFSFileName[];
  73. extern char IFSName[];
  74. extern int  bailout;        /* user input bailout value */
  75. extern char useinitorbit;
  76. extern struct complex initorbit;
  77. extern int  display3d;        /* 3D display flag: 0 = OFF */
  78. extern int  loaded3d;
  79. extern char readname[];     /* name of fractal input file */
  80. extern int  showfile;        /* has file been displayed yet? */
  81. extern int  transparent[];
  82. extern char preview;        /* 3D preview mode flag */
  83. extern char showbox;        /* flag to show box and vector in preview */
  84. extern int  RANDOMIZE;        /* Color randomizing factor */
  85. extern int  Targa_Out;  /* Selects full color with light source fills */
  86. extern int  Ambient;        /* Darkness of shadows in light source */
  87. extern int  haze;        /* Amount of haze to factor in in full color */
  88. extern char light_name[];    /* Name of full color .TGA file */
  89. extern int previewfactor;
  90. extern int BRIEF;
  91. extern int RAY;
  92. extern int xtrans;
  93. extern int ytrans;
  94. extern int red_crop_left;
  95. extern int red_crop_right;
  96. extern int blue_crop_left;
  97. extern int blue_crop_right;
  98. extern int red_bright;
  99. extern int blue_bright;
  100. extern int xadjust;
  101. extern int eyeseparation;
  102. extern int glassestype;
  103. extern unsigned char trigndx[];
  104. extern int rotate_lo,rotate_hi;
  105. extern int far *ranges;
  106. extern int rangeslen;
  107. extern char CommandFile[80];
  108. extern char CommandName[ITEMNAMELEN+1];
  109. extern char CommandComment1[57];
  110. extern char CommandComment2[57];
  111. extern char usr_stdcalcmode;
  112.  
  113. extern int  colorstate;     /* comments in cmdfiles */
  114. extern int  colors;
  115. extern int  gotrealdac;
  116. extern int  reallyega;
  117. extern char colorfile[];
  118. extern int  mapset;
  119. extern char MAP_name[];
  120. extern unsigned char dacbox[256][3];
  121. extern char far *mapdacbox;
  122.  
  123. #ifdef WINFRACT
  124. extern char suffix[4096];
  125. #else
  126. extern char dstack[4096];
  127. #endif
  128. extern char boxx[8192];
  129. extern char s_cantopen[];
  130. extern char s_cantwrite[];
  131. extern char s_cantcreate[];
  132. extern char s_cantunderstand[];
  133. extern char s_cantfind[];
  134.  
  135.  
  136. extern int fullscreen_prompt(char *hdg,int numprompts,char * far *prompts,
  137.            struct fullscreenvalues values[],int options,int fkeymask,
  138.            char far *extrainfo);
  139.  
  140. /* fullscreen_choice options */
  141. #define CHOICERETURNKEY 1
  142. #define CHOICEMENU    2
  143. #define CHOICEHELP    4
  144. int  fullscreen_choice(
  145.          int options, char *hdg, char *hdg2, char *instr, int numchoices,
  146.          char **choices, int *attributes, int boxwidth, int boxdepth,
  147.          int colwidth, int current, void (*formatitem)(),
  148.          char *speedstring, int (*speedprompt)(), int (*checkkey)());
  149.  
  150.  
  151. void miscovl_overlay() { }    /* for restore_active_ovly */
  152.  
  153. extern char s_real[];
  154. extern char s_imag[];
  155. extern char s_mult[];
  156. extern char s_sum[];
  157. extern char s_zmag[];
  158. extern char s_bof60[];
  159. extern char s_bof61[];
  160. extern char s_maxiter[];
  161.  
  162. #ifdef WINFRACT
  163. #endif
  164. extern FILE *parmfile;
  165.  
  166. #ifdef C6
  167. #pragma optimize("e",off)  /* MSC 6.00A messes up next rtn with "e" on */
  168. #endif
  169. void make_batch_file()
  170. {
  171.    int i,numparms;
  172.    char inpcommandfile[80],inpcommandname[ITEMNAMELEN+1];
  173.    char inpcomment1[57],inpcomment2[57];
  174.    struct fullscreenvalues paramvalues[8];
  175.    char *choices[8];
  176.    int gotinfile;
  177.    char outname[81],buf[256],buf2[128];
  178.    FILE *infile;
  179.    char colorspec[14];
  180.    int maxcolor;
  181.    char *sptr,*sptr2;
  182.    int oldhelpmode;
  183.  
  184.    ENTER_OVLY(OVLY_MISCOVL);
  185.    stackscreen();
  186.    oldhelpmode = helpmode;
  187.    helpmode = HELPPARMFILE;
  188.  
  189.    strcpy(colorspec,"n");
  190.    maxcolor = colors;
  191.    if (gotrealdac && !reallyega) {
  192.       --maxcolor;
  193.       if (maxit < maxcolor) maxcolor = maxit;
  194.       if (inside  > 0 && inside    > maxcolor) maxcolor = inside;
  195.       if (outside > 0 && outside   > maxcolor) maxcolor = outside;
  196.       if (distest < 0 && 0-distest > maxcolor) maxcolor = 0-distest;
  197.       if (decomp[0] > maxcolor) maxcolor = decomp[0] - 1;
  198.       if (potflag && potparam[0] >= maxcolor) maxcolor = potparam[0];
  199.       if (++maxcolor > 256) maxcolor = 256;
  200.       if (colorstate == 0) {      /* default colors */
  201.      if (mapdacbox) {
  202.         colorspec[0] = '@';
  203.         sptr = MAP_name;
  204.         }
  205.      }
  206.       else if (colorstate == 2) { /* colors match colorfile */
  207.      colorspec[0] = '@';
  208.      sptr = colorfile;
  209.      }
  210.       else              /* colors match no .map that we know of */
  211.      colorspec[0] = 'y';
  212.       if (colorspec[0] == '@') {
  213.      if ((sptr2 = strrchr(sptr,'\\'))) sptr = sptr2 + 1;
  214.      if ((sptr2 = strrchr(sptr,':')))  sptr = sptr2 + 1;
  215.      strncpy(&colorspec[1],sptr,12);
  216.      colorspec[13] = 0;
  217.      }
  218.       }
  219.    strcpy(inpcommandfile,CommandFile);
  220.    strcpy(inpcommandname,CommandName);
  221.    strcpy(inpcomment1,CommandComment1);
  222.    strcpy(inpcomment2,CommandComment2);
  223.    if (CommandName[0] == 0)
  224.       strcpy(inpcommandname,"test");
  225.  
  226.    while (1) {
  227.  
  228. prompt_user:
  229.       choices[0] = "Parameter file";
  230.       paramvalues[0].type = 0x100+56;
  231.       paramvalues[0].uval.sbuf = inpcommandfile;
  232.       choices[1] = "Name";
  233.       paramvalues[1].type = 0x100+ITEMNAMELEN;
  234.       paramvalues[1].uval.sbuf = inpcommandname;
  235.       choices[2] = "Main comment";
  236.       paramvalues[2].type = 0x100+56;
  237.       paramvalues[2].uval.sbuf = inpcomment1;
  238.       choices[3] = "Second comment";
  239.       paramvalues[3].type = 0x100+56;;
  240.       paramvalues[3].uval.sbuf = inpcomment2;
  241.       numparms = 4;
  242.       if (gotrealdac && !reallyega) {
  243.      choices[4] = "Record colors?";
  244.      paramvalues[4].type = 0x100+13;
  245.      paramvalues[4].uval.sbuf = colorspec;
  246.      choices[5] = "    (no | yes for full info | @filename to point to a map file)";
  247.      paramvalues[5].type = '*';
  248.      choices[6] = "# of colors";
  249.      paramvalues[6].type = 'i';
  250.      paramvalues[6].uval.ival = maxcolor;
  251.      choices[7] = "    (if recording full color info)";
  252.      paramvalues[7].type = '*';
  253.      numparms = 8;
  254.      }
  255.  
  256.       if (fullscreen_prompt("Save Current Parameters",
  257.                 numparms,choices,paramvalues,0,0,NULL) < 0)
  258.      break;
  259.  
  260.       strcpy(CommandFile,inpcommandfile);
  261.       if (strchr(CommandFile,'.') == NULL)
  262.      strcat(CommandFile,".par"); /* default extension .par */
  263.       strcpy(CommandName,inpcommandname);
  264.       strcpy(CommandComment1,inpcomment1);
  265.       strcpy(CommandComment2,inpcomment2);
  266.       if (paramvalues[6].uval.ival > 0 && paramvalues[6].uval.ival <= 256)
  267.      maxcolor = paramvalues[6].uval.ival;
  268.  
  269.       strcpy(outname,CommandFile);
  270.       gotinfile = 0;
  271.       if (access(CommandFile,0) == 0) { /* file exists */
  272.      gotinfile = 1;
  273.      if (access(CommandFile,6)) {
  274.         sprintf(buf,s_cantwrite,CommandFile);
  275.         stopmsg(0,buf);
  276.         continue;
  277.         }
  278.      i = strlen(outname);
  279.      while (--i >= 0 && outname[i] != '\\')
  280.      outname[i] = 0;
  281.      strcat(outname,"fractint.tmp");
  282.      infile = fopen(CommandFile,"rt");
  283.      setvbuf(infile,suffix,_IOFBF,4096); /* improves speed */
  284.      }
  285.       if ((parmfile = fopen(outname,"wt")) == NULL) {
  286.      sprintf(buf,s_cantcreate,outname);
  287.      stopmsg(0,buf);
  288.      if (gotinfile) fclose(infile);
  289.      continue;
  290.      }
  291. #ifndef WINFRACT
  292.       setvbuf(infile,boxx,_IOFBF,8192); /* improves speed */
  293. #endif
  294.  
  295.       if (gotinfile) {
  296.      while (file_gets(buf,255,infile) >= 0) {
  297.         if (strchr(buf,'{')                    /* entry heading? */
  298.           && sscanf(buf," %40[^ \t({]",buf2)
  299.           && stricmp(buf2,CommandName) == 0) { /* entry with same name */
  300.            sprintf(buf2,"File already has an entry named %s\n\
  301. Continue to replace it, Cancel to back out",CommandName);
  302.            if (stopmsg(18,buf2) < 0) {        /* cancel */
  303.           fclose(infile);
  304.           fclose(parmfile);
  305.           unlink(outname);
  306.           goto prompt_user;
  307.           }
  308.            while (strchr(buf,'}') == NULL
  309.          && file_gets(buf,255,infile) > 0 ) { } /* skip to end of set */
  310.            break;
  311.            }
  312.         fputs(buf,parmfile);
  313.         fputc('\n',parmfile);
  314.         }
  315.      }
  316.  
  317.       fprintf(parmfile,"%-19s{",CommandName);
  318.       if (CommandComment1[0]) fprintf(parmfile," ; %s",CommandComment1);
  319.       fputc('\n',parmfile);
  320.       if (CommandComment2[0])
  321.      fprintf(parmfile,"                     ; %s\n",CommandComment2);
  322.       write_batch_parms(parmfile,colorspec,maxcolor); /* write the parameters */
  323.       fprintf(parmfile,"  }\n\n");
  324.  
  325.       if (gotinfile) {    /* copy the rest of the file */
  326.      while ((i = file_gets(buf,255,infile)) == 0) { } /* skip blanks */
  327.      while (i >= 0) {
  328.         fputs(buf,parmfile);
  329.         fputc('\n',parmfile);
  330.         i = file_gets(buf,255,infile);
  331.         }
  332.      fclose(infile);
  333.      }
  334.       fclose(parmfile);
  335.       if (gotinfile) {    /* replace the original file with the new */
  336.      unlink(CommandFile);          /* success assumed on these lines       */
  337.      rename(outname,CommandFile); /* since we checked earlier with access */
  338.      }
  339.  
  340.       break;
  341.       }
  342.  
  343.    helpmode = oldhelpmode;
  344.    unstackscreen();
  345.    EXIT_OVLY;
  346. }
  347. #ifdef C6
  348. #pragma optimize("e",on)  /* back to normal */
  349. #endif
  350.  
  351. static struct write_batch_data { /* buffer for parms to break lines nicely */
  352.    int len;
  353.    char buf[513];
  354.    } *wbdata;
  355.  
  356. #ifdef WINFRACT
  357. #endif
  358. void write_batch_parms(FILE *batch,char *colorinf,int maxcolor)
  359. {
  360.    int i,j,k;
  361.    double Xctr, Yctr, Magnification;
  362.    struct write_batch_data wb_data;
  363.    char *sptr;
  364.    char buf[81];
  365.  
  366.    wbdata = &wb_data;
  367.    wb_data.len = 0; /* force first parm to start on new line */
  368.  
  369.    if (display3d <= 0) { /* a fractal was generated */
  370.  
  371.       /****** fractal only parameters in this section *******/
  372.       put_parm(" reset");
  373.  
  374.       if (*(sptr = curfractalspecific->name) == '*') ++sptr;
  375.       put_parm( " type=%s",sptr);
  376.  
  377.       if (fractype == FORMULA || fractype == FFORMULA)
  378.      put_parm( " formulafile=%s formulaname=%s",FormFileName,FormName);
  379.       if (fractype == LSYSTEM)
  380.     put_parm( " lfile=%s lname=%s",LFileName,LName);
  381.       if (fractype == IFS || fractype == IFS3D)
  382.     put_parm( " ifsfile=%s ifs=%s",IFSFileName,IFSName);
  383.  
  384.       showtrig(buf); /* this function is in miscres.c */
  385.       if (buf[0])
  386.      put_parm(buf);
  387.  
  388.       if (usr_stdcalcmode != 'g')
  389.      put_parm(" passes=%c",usr_stdcalcmode);
  390.  
  391.       if (usemag && cvtcentermag(&Xctr, &Yctr, &Magnification)) {
  392.      put_parm(" center-mag=");
  393.      put_parm((delmin > 1000) ? "%g/%g/%g"
  394.                   : "%+20.17lf/%+20.17lf/%+20.17lf",
  395.           Xctr,Yctr,Magnification);
  396.      }
  397.       else {
  398.      int xdigits,ydigits;
  399.      put_parm( " corners=");
  400.      xdigits = getprec(xxmin,xxmax,xx3rd);
  401.      ydigits = getprec(yymin,yymax,yy3rd);
  402.      put_float(0,xxmin,xdigits);
  403.      put_float(1,xxmax,xdigits);
  404.      put_float(1,yymin,ydigits);
  405.      put_float(1,yymax,ydigits);
  406.      if (xx3rd != xxmin || yy3rd != yymin) {
  407.         put_float(1,xx3rd,xdigits);
  408.         put_float(1,yy3rd,ydigits);
  409.         }
  410.      }
  411.  
  412.       for (i = 3; i >= 0; --i)
  413.      if (param[i] != 0.0) break;
  414.       if (i >= 0) {
  415.      put_parm(" params=%.15g",param[0]);
  416.      for (j = 1; j <= i; ++j)
  417.         put_parm("/%.15g",param[j]);
  418.      }
  419.  
  420.       if(useinitorbit == 2)
  421.      put_parm( " initorbit=pixel");
  422.       else if(useinitorbit == 1)
  423.      put_parm( " initorbit=%.15g/%.15g",initorbit.x,initorbit.y);
  424.  
  425.       if (floatflag)
  426.      put_parm( " float=y");
  427.  
  428.       if (maxit != 150)
  429.      put_parm(" maxiter=%d",maxit);
  430.  
  431.       if(bailout && (potflag == 0 || potparam[2] == 0.0))
  432.      put_parm( " bailout=%d",bailout);
  433.       if(fillcolor != -1) {
  434.        put_parm(" fillcolor=");
  435.     put_parm( "%d",fillcolor);
  436.       }
  437.       if (inside != 1) {
  438.      put_parm(" inside=");
  439.      if (inside == -1)
  440.         put_parm( s_maxiter);
  441.      else if (inside == -59)
  442.         put_parm(s_zmag);
  443.      else if (inside == -60)
  444.         put_parm(s_bof60);
  445.      else if (inside == -61)
  446.         put_parm(s_bof61);
  447.      else
  448.         put_parm( "%d",inside);
  449.      }
  450.       if (outside != -1)
  451.       {
  452.      put_parm(" outside=");
  453.      if (outside == -2)
  454.         put_parm(s_real);
  455.      else if (outside == -3)
  456.         put_parm(s_imag);
  457.      else if (outside == -4)
  458.         put_parm(s_mult);
  459.      else if (outside == -5)
  460.         put_parm(s_sum);
  461.      else
  462.         put_parm( "%d",outside);
  463.       }
  464.  
  465.       if(LogFlag) {
  466.      put_parm( " logmap=");
  467.      if(LogFlag == -1)
  468.         put_parm( "old");
  469.      else if(LogFlag == 1)
  470.         put_parm( "yes");
  471.      else
  472.         put_parm( "%d", LogFlag);
  473.      }
  474.  
  475.       if (potflag) {
  476.      put_parm( " potential=%d/%g/%d",
  477.          (int)potparam[0],potparam[1],(int)potparam[2]);
  478.      if(pot16bit)
  479.         put_parm( "/16bit");
  480.      }
  481.       if (invert)
  482.      put_parm( " invert=%g/%g/%g",
  483.          inversion[0], inversion[1], inversion[2]);
  484.       if (decomp[0])
  485.      put_parm( " decomp=%d", decomp[0]);
  486.       if (distest)
  487.      put_parm( " distest=%d/%d", distest, distestwidth);
  488.       if (usr_biomorph != -1)
  489.      put_parm( " biomorph=%d", usr_biomorph);
  490.       if (finattract)
  491.      put_parm(" finattract=y");
  492.  
  493.       if (forcesymmetry != 999) {
  494.      put_parm( " symmetry=");
  495.      if (forcesymmetry==XAXIS)
  496.         put_parm("xaxis");
  497.      else if(forcesymmetry==YAXIS)
  498.         put_parm("yaxis");
  499.      else if(forcesymmetry==XYAXIS)
  500.         put_parm("xyaxis");
  501.      else if(forcesymmetry==ORIGIN)
  502.         put_parm("origin");
  503.      else if(forcesymmetry==PI_SYM)
  504.         put_parm("pi");
  505.      else
  506.         put_parm("none");
  507.      }
  508.  
  509.       if (periodicitycheck != 1)
  510.      put_parm( " periodicity=%d",periodicitycheck);
  511.  
  512.       if (rflag)
  513.      put_parm( " rseed=%d",rseed);
  514.  
  515.       if (rangeslen) {
  516.      put_parm(" ranges=");
  517.      i = 0;
  518.      while (i < rangeslen) {
  519.         if (i)
  520.            put_parm("/");
  521.         if (ranges[i] == -1) {
  522.            put_parm("-%d/",ranges[++i]);
  523.            ++i;
  524.            }
  525.         put_parm("%d",ranges[i++]);
  526.         }
  527.      }
  528.       }
  529.  
  530.    if (display3d >= 1) {
  531.       /***** 3d transform only parameters in this section *****/
  532.       put_parm( " 3d=yes");
  533.       if (loaded3d == 0)
  534.      put_filename("filename",readname);
  535.       if (SPHERE) {
  536.      put_parm( " sphere=y");
  537.      put_parm( " latitude=%d/%d", THETA1, THETA2);
  538.      put_parm( " longitude=%d/%d", PHI1, PHI2);
  539.      put_parm( " radius=%d", RADIUS);
  540.      }
  541.       put_parm( " scalexyz=%d/%d", XSCALE, YSCALE);
  542.       put_parm( " roughness=%d", ROUGH);
  543.       put_parm( " waterline=%d", WATERLINE);
  544.       if (FILLTYPE)
  545.      put_parm( " filltype=%d", FILLTYPE);
  546.       if (transparent[0] || transparent[1])
  547.      put_parm( " transparent=%d/%d", transparent[0],transparent[1]);
  548.       if (preview) {
  549.      put_parm( " preview=y");
  550.      if (showbox)
  551.         put_parm( " showbox=y");
  552.      put_parm( " coarse=%d",previewfactor);
  553.      }
  554.       if (RAY) {
  555.      put_parm( " ray=%d",RAY);
  556.      if (BRIEF)
  557.         put_parm(" brief=y");
  558.      }
  559.       if (FILLTYPE > 4) {
  560.      put_parm( " lightsource=%d/%d/%d", XLIGHT, YLIGHT, ZLIGHT);
  561.      if (LIGHTAVG)
  562.         put_parm( " smoothing=%d", LIGHTAVG);
  563.      }
  564.       if (RANDOMIZE)
  565.      put_parm( " randomize=%d",RANDOMIZE);
  566.  
  567.       if (Targa_Out)
  568.      put_parm( " fullcolor=y");
  569.       if (Ambient)
  570.      put_parm( " ambient=%d",Ambient);
  571.       if (haze)
  572.      put_parm( " haze=%d",haze);
  573.       }
  574.  
  575.    if (display3d) {        /* universal 3d */
  576.       /***** common (fractal & transform) 3d parameters in this section *****/
  577.       if (!SPHERE || display3d < 0)
  578.      put_parm( " rotation=%d/%d/%d", XROT, YROT, ZROT);
  579.       put_parm( " perspective=%d", ZVIEWER);
  580.       put_parm( " xyshift=%d/%d", XSHIFT, YSHIFT);
  581.       if(xtrans || ytrans)
  582.      put_parm( " xyadjust=%d/%d",xtrans,ytrans);
  583.       if(glassestype) {
  584.      put_parm( " stereo=%d",glassestype);
  585.      put_parm( " interocular=%d",eyeseparation);
  586.      put_parm( " converge=%d",xadjust);
  587.      put_parm( " crop=%d/%d/%d/%d",
  588.          red_crop_left,red_crop_right,blue_crop_left,blue_crop_right);
  589.      put_parm( " bright=%d/%d",
  590.          red_bright,blue_bright);
  591.      }
  592.       }
  593.  
  594.    /***** universal parameters in this section *****/
  595.  
  596.    if (*colorinf != 'n') {
  597.       put_parm(" colors=");
  598.       if (*colorinf == '@')
  599.      put_parm(colorinf);
  600.       else {
  601.      int curc,scanc,force,diffmag;
  602.      int delta,diff1[4][3],diff2[4][3];
  603.      curc = force = 0;
  604.      while (1) {
  605.         /* emit color in rgb 3 char encoded form */
  606.         for (j = 0; j < 3; ++j) {
  607.            if ((k = dacbox[curc][j]) < 10) k += '0';
  608.            else if (k < 36)            k += ('A' - 10);
  609.            else                   k += ('_' - 36);
  610.            buf[j] = k;
  611.            }
  612.         buf[3] = 0;
  613.         put_parm(buf);
  614.         if (++curc >= maxcolor)     /* quit if done last color */
  615.            break;
  616.         /* Next a P Branderhorst special, a tricky scan for smooth-shaded
  617.            ranges which can be written as <nn> to compress .par file entry.
  618.            Method used is to check net change in each color value over
  619.            spans of 2 to 5 color numbers.  First time for each span size
  620.            the value change is noted.  After first time the change is
  621.            checked against noted change.  First time it differs, a
  622.            a difference of 1 is tolerated and noted as an alternate
  623.            acceptable change.  When change is not one of the tolerated
  624.            values, loop exits. */
  625.         if (force) {
  626.            --force;
  627.            continue;
  628.            }
  629.         scanc = curc;
  630.         while (scanc < maxcolor) {     /* scan while same diff to next */
  631.            if ((i = scanc - curc) > 3) /* check spans up to 4 steps */
  632.           i = 3;
  633.            for (k = 0; k <= i; ++k) {
  634.           for (j = 0; j < 3; ++j) { /* check pattern of chg per color */
  635.              delta = (int)dacbox[scanc][j] - (int)dacbox[scanc-k-1][j];
  636.              if (k == scanc - curc)
  637.             diff1[k][j] = diff2[k][j] = delta;
  638.              else
  639.             if (delta != diff1[k][j] && delta != diff2[k][j]) {
  640.                diffmag = abs(delta - diff1[k][j]);
  641.                if (diff1[k][j] != diff2[k][j] || diffmag != 1)
  642.                   break;
  643.                diff2[k][j] = delta;
  644.                }
  645.              }
  646.           if (j < 3) break; /* must've exited from inner loop above */
  647.           }
  648.            if (k <= i) break;   /* must've exited from inner loop above */
  649.            ++scanc;
  650.            }
  651.         /* now scanc-1 is next color which must be written explicitly */
  652.         if (scanc - curc > 2) { /* good, we have a shaded range */
  653.            if (scanc != maxcolor) {
  654.           if (diffmag < 3) {  /* not a sharp slope change? */
  655.              force = 2;       /* force more between ranges, to stop  */
  656.              --scanc;          /* "drift" when load/store/load/store/ */
  657.              }
  658.           if (k) {          /* more of the same             */
  659.              force += k;
  660.              --scanc;
  661.              }
  662.           }
  663.            if (--scanc - curc > 1) {
  664.           put_parm("<%d>",scanc-curc);
  665.           curc = scanc;
  666.           }
  667.            else           /* changed our mind */
  668.           force = 0;
  669.            }
  670.         }
  671.      }
  672.       }
  673.  
  674.    if (rotate_lo != 1 || rotate_hi != 255)
  675.       put_parm( " cyclerange=%d/%d",rotate_lo,rotate_hi);
  676.  
  677.    while (wbdata->len) /* flush the buffer */
  678.       put_parm_line();
  679. }
  680.  
  681. static void put_filename(char *keyword,char *fname)
  682. {
  683.    char *p;
  684.    if (*fname && !endswithslash(fname)) {
  685.       if ((p = strrchr(fname,'\\')))
  686.      if (*(fname = p+1) == 0) return;
  687.       put_parm(" %s=%s",keyword,fname);
  688.       }
  689. }
  690.  
  691. static void put_parm(char *parm,...)
  692. {
  693.    char *bufptr;
  694.    va_list args;
  695.    va_start(args,parm);
  696.    if (*parm == ' '             /* starting a new parm */
  697.      && wbdata->len == 0)    /* skip leading space */
  698.       ++parm;
  699.    bufptr = wbdata->buf + wbdata->len;
  700.    vsprintf(bufptr,parm,args);
  701.    while (*(bufptr++))
  702.       ++wbdata->len;
  703.    while (wbdata->len > 200)
  704.       put_parm_line();
  705. }
  706.  
  707. #define NICELINELEN 72
  708. #define MAXLINELEN  76
  709.  
  710. static void put_parm_line()
  711. {
  712.    int len,c;
  713.    if ((len = wbdata->len) > NICELINELEN) {
  714.       len = NICELINELEN+1;
  715.       while (--len != 0 && wbdata->buf[len] != ' ') { }
  716.       if (len == 0) {
  717.      len = NICELINELEN-1;
  718.      while (++len < MAXLINELEN
  719.        && wbdata->buf[len] && wbdata->buf[len] != ' ') { }
  720.      }
  721.       }
  722.    c = wbdata->buf[len];
  723.    wbdata->buf[len] = 0;
  724.    fputs("  ",parmfile);
  725.    fputs(wbdata->buf,parmfile);
  726.    if (c && c != ' ')
  727.       fputc('\\',parmfile);
  728.    fputc('\n',parmfile);
  729.    if ((wbdata->buf[len] = c) == ' ')
  730.       ++len;
  731.    wbdata->len -= len;
  732.    strcpy(wbdata->buf,wbdata->buf+len);
  733. }
  734.  
  735. static int getprec(double a,double b,double c)
  736. {
  737.    double diff,temp;
  738.    int digits;
  739.    double highv = 1.0E20;
  740.    if ((diff = fabs(a - b)) == 0.0) diff = highv;
  741.    if ((temp = fabs(a - c)) == 0.0) temp = highv;
  742.    if (temp < diff) diff = temp;
  743.    if ((temp = fabs(b - c)) == 0.0) temp = highv;
  744.    if (temp < diff) diff = temp;
  745.    digits = 5;
  746.    while (diff < 1.0 && digits < 17) {
  747.       diff *= 10;
  748.       ++digits;
  749.       }
  750.    return((digits < 6) ? 6 : digits);
  751. }
  752.  
  753. static void put_float(int slash,double fnum,int prec)
  754. {  char buf[40];
  755.    char *bptr, *dptr;
  756.    bptr = buf;
  757.    if (slash)
  758.       *(bptr++) = '/';
  759.    sprintf(bptr,"%1.*f",prec,fnum);
  760.    if ((dptr = strchr(bptr,'.'))) {
  761.       ++dptr;
  762.       bptr = buf + strlen(buf);
  763.       while (--bptr > dptr && *bptr == '0')
  764.      *bptr = 0;
  765.       }
  766.    put_parm(buf);
  767. }
  768.  
  769. void shell_to_dos()
  770. {
  771. #ifndef WINFRACT
  772.    char *comspec;
  773.    /* from fractint.c & calls no ovlys, doesn't need ENTER_OVLY */
  774.    if ((comspec = getenv("COMSPEC")) == NULL)
  775.       printf("Cannot find COMMAND.COM.\n");
  776.    else {
  777.       putenv("PROMPT='EXIT' returns to FRACTINT.$_$p$g");
  778.       spawnl(P_WAIT, comspec, NULL);
  779.       }
  780. #endif
  781. }
  782.  
  783.  
  784. void showfreemem()
  785. {
  786.    char *tempptr;
  787.    unsigned char huge *fartempptr;
  788.    unsigned i,i2;
  789.    long j,j2;
  790.    ENTER_OVLY(OVLY_MISCOVL);
  791.    printf("\n CPU type: %d  FPU type: %d  IIT FPU: %d  Video: %d\n\n",
  792.       cpu, fpu, iit, video_type);
  793.    i = j = 0;
  794.    i2 = 0x8000;
  795.    while ((i2 >>= 1) != 0)
  796.       if ((tempptr = malloc(i+i2)) != NULL) {
  797.      free(tempptr);
  798.      i += i2;
  799.      }
  800.    printf(" %d NEAR bytes free \n", i);
  801.    j2 = 0x80000;
  802.    while ((j2 >>= 1) != 0)
  803.       if ((fartempptr = (unsigned char huge *)farmemalloc(j+j2)) != NULL) {
  804.      farmemfree((void far*)fartempptr);
  805.      j += j2;
  806.      }
  807.    printf(" %ld FAR bytes free \n\n press any key to continue...\n", j);
  808.    getakey();
  809.    EXIT_OVLY;
  810. }
  811.  
  812.  
  813. edit_text_colors()
  814. {
  815.    extern int debugflag;
  816.    extern int lookatmouse;
  817.    int save_debugflag,save_lookatmouse;
  818.    int row,col,bkgrd;
  819.    int rowf,colf,rowt,colt;
  820.    char far *vidmem;
  821.    char far *savescreen;
  822.    char far *farp1; char far *farp2;
  823.    int i,j,k;
  824.    ENTER_OVLY(OVLY_MISCOVL);
  825.    save_debugflag = debugflag;
  826.    save_lookatmouse = lookatmouse;
  827.    debugflag = 0;   /* don't get called recursively */
  828.    lookatmouse = 2; /* text mouse sensitivity */
  829.    row = col = bkgrd = rowt = rowf = colt = colf = 0;
  830.    vidmem = MK_FP(0xB800,0);
  831.    while (1) {
  832.       if (row < 0)  row = 0;
  833.       if (row > 24) row = 24;
  834.       if (col < 0)  col = 0;
  835.       if (col > 79) col = 79;
  836.       movecursor(row,col);
  837.       i = getakey();
  838.       if (i >= 'a' && i <= 'z') i -= 32; /* uppercase */
  839.       switch (i) {
  840.      case 27: /* esc */
  841.         debugflag = save_debugflag;
  842.         lookatmouse = save_lookatmouse;
  843.         movecursor(25,80);
  844.         EXIT_OVLY;
  845.         return 0;
  846.      case '/':
  847.         farp1 = savescreen = farmemalloc(4000L);
  848.         farp2 = vidmem;
  849.         for (i = 0; i < 4000; ++i) { /* save and blank */
  850.            *(farp1++) = *farp2;
  851.            *(farp2++) = 0;
  852.            }
  853.         for (i = 0; i < 8; ++i)      /* 8 bkgrd attrs */
  854.            for (j = 0; j < 16; ++j) { /* 16 fgrd attrs */
  855.           k = i*16 + j;
  856.           farp1 = vidmem + i*320 + j*10;
  857.           *(farp1++) = ' '; *(farp1++) = k;
  858.           *(farp1++) = i+'0'; *(farp1++) = k;
  859.           *(farp1++) = (j < 10) ? j+'0' : j+'A'-10; *(farp1++) = k;
  860.           *(farp1++) = ' '; *(farp1++) = k;
  861.           }
  862.         getakey();
  863.         farp1 = vidmem;
  864.         farp2 = savescreen;
  865.         for (i = 0; i < 4000; ++i) /* restore */
  866.            *(farp1++) = *(farp2++);
  867.         farmemfree(savescreen);
  868.         break;
  869.      case ',':
  870.         rowf = row; colf = col; break;
  871.      case '.':
  872.         rowt = row; colt = col; break;
  873.      case ' ': /* next color is background */
  874.         bkgrd = 1; break;
  875.      case 1075: /* cursor left  */
  876.         --col; break;
  877.      case 1077: /* cursor right */
  878.         ++col; break;
  879.      case 1072: /* cursor up    */
  880.         --row; break;
  881.      case 1080: /* cursor down  */
  882.         ++row; break;
  883.      case 13:   /* enter */
  884.         *(vidmem + row*160 + col*2) = getakey();
  885.         break;
  886.      default:
  887.         if (i >= '0' && i <= '9')      i -= '0';
  888.         else if (i >= 'A' && i <= 'F') i -= 'A'-10;
  889.         else break;
  890.         for (j = rowf; j <= rowt; ++j)
  891.            for (k = colf; k <= colt; ++k) {
  892.           farp1 = vidmem + j*160 + k*2 + 1;
  893.           if (bkgrd) *farp1 = (*farp1 & 15) + i * 16;
  894.           else         *farp1 = (*farp1 & 0xf0) + i;
  895.           }
  896.         bkgrd = 0;
  897.      }
  898.       }
  899. }
  900.  
  901.  
  902. extern int badconfig;
  903. extern struct videoinfo far videotable[];
  904. extern struct videoinfo far *vidtbl;
  905. extern int vidtbllen;
  906. extern int tabmode;
  907. extern int adapter;
  908. static int *entsptr;
  909. static int modes_changed;
  910. extern int mode7text;
  911.  
  912. int select_video_mode(int curmode)
  913. {
  914.    int entnums[MAXVIDEOMODES];
  915.    int attributes[MAXVIDEOMODES];
  916.    int i,j,k,ret;
  917.    int oldtabmode,oldhelpmode;
  918.  
  919.    ENTER_OVLY(OVLY_MISCOVL);
  920.  
  921.    load_fractint_cfg(0);    /* load fractint.cfg to extraseg */
  922.  
  923.    for (i = 0; i < vidtbllen; ++i) { /* init tables */
  924.       entnums[i] = i;
  925.       attributes[i] = 1;
  926.       }
  927.    entsptr = entnums;        /* for indirectly called subroutines */
  928.  
  929.    qsort(entnums,vidtbllen,sizeof(entnums[0]),entcompare); /* sort modes */
  930.  
  931.    /* pick default mode */
  932.    if (curmode < 0) {
  933.       switch (video_type) { /* set up a reasonable default (we hope) */
  934.      case 1:  videoentry.videomodeax = 8;    /* hgc */
  935.           videoentry.colors = 2;
  936.           break;
  937.      case 2:  videoentry.videomodeax = 4;    /* cga */
  938.           videoentry.colors = 4;
  939.           break;
  940.      case 3:  videoentry.videomodeax = 16;    /* ega */
  941.           videoentry.colors = 16;
  942.           if (mode7text) {        /* egamono */
  943.              videoentry.videomodeax = 15;
  944.              videoentry.colors = 2;
  945.              }
  946.           break;
  947.      default: videoentry.videomodeax = 19;    /* mcga/vga? */
  948.           videoentry.colors = 256;
  949.           break;
  950.      }
  951.       }
  952.    else
  953.       far_memcpy((char far *)&videoentry,(char far *)&videotable[curmode],
  954.          sizeof(videoentry));
  955.    for (i = 0; i < vidtbllen; ++i) { /* find default mode */
  956.       if ( videoentry.videomodeax == vidtbl[entnums[i]].videomodeax
  957.     && videoentry.colors      == vidtbl[entnums[i]].colors
  958.     && (curmode < 0
  959.         || far_memcmp((char far *)&videoentry,(char far *)&vidtbl[entnums[i]],
  960.               sizeof(videoentry)) == 0))
  961.      break;
  962.       }
  963.    if (i >= vidtbllen) /* no match, default to first entry */
  964.       i = 0;
  965.  
  966.    oldtabmode = tabmode;
  967.    oldhelpmode = helpmode;
  968.    modes_changed = 0;
  969.    tabmode = 0;
  970.    helpmode = HELPVIDSEL;
  971.    i = fullscreen_choice(CHOICEHELP,"Select Video Mode",
  972.  "key...name......................xdot.ydot.colr.comment..................",
  973.           NULL,vidtbllen,NULL,attributes,
  974.           1,16,72,i,format_item,NULL,NULL,check_modekey);
  975.    tabmode = oldtabmode;
  976.    helpmode = oldhelpmode;
  977.    if (i == -1) {
  978.    static char far msg[]={"Save new function key assignments or cancel changes?"};
  979.       if (modes_changed /* update fractint.cfg for new key assignments */
  980.     && badconfig == 0
  981.     && stopmsg(22,msg) == 0)
  982.      update_fractint_cfg();
  983.       EXIT_OVLY;
  984.       return(-1);
  985.       }
  986.    if (i < 0)    /* picked by function key */
  987.       i = -1 - i;
  988.    else     /* picked by Enter key */
  989.       i = entnums[i];
  990.    far_memcpy((char far *)&videoentry,(char far *)&vidtbl[i],
  991.           sizeof(videoentry));  /* the selected entry now in videoentry */
  992.  
  993.    /* copy fractint.cfg table to resident table, note selected entry */
  994.    j = k = 0;
  995.    far_memset((char far *)videotable,0,sizeof(*vidtbl)*MAXVIDEOTABLE);
  996.    for (i = 0; i < vidtbllen; ++i) {
  997.       if (vidtbl[i].keynum > 0) {
  998.      far_memcpy((char far *)&videotable[j],(char far *)&vidtbl[i],
  999.             sizeof(*vidtbl));
  1000.      if (far_memcmp((char far *)&videoentry,(char far *)&vidtbl[i],
  1001.             sizeof(videoentry)) == 0)
  1002.         k = vidtbl[i].keynum;
  1003.      if (++j >= MAXVIDEOTABLE-1)
  1004.         break;
  1005.      }
  1006.       }
  1007.    if ((ret = k) == 0) { /* selected entry not a copied (assigned to key) one */
  1008.       far_memcpy((char far *)&videotable[MAXVIDEOTABLE-1],
  1009.          (char far *)&videoentry,sizeof(*vidtbl));
  1010.       ret = 1400; /* special value for check_vidmode_key */
  1011.       }
  1012.  
  1013.    if (modes_changed /* update fractint.cfg for new key assignments */
  1014.      && badconfig == 0)
  1015.       update_fractint_cfg();
  1016.  
  1017.    EXIT_OVLY;
  1018.    return(ret);
  1019. }
  1020.  
  1021. static void format_item(int choice,char *buf)
  1022. {
  1023.    char kname[5];
  1024.    char biosflag;
  1025.    far_memcpy((char far *)&videoentry,(char far *)&vidtbl[entsptr[choice]],
  1026.           sizeof(videoentry));
  1027.    vidmode_keyname(videoentry.keynum,kname);
  1028.    biosflag = (videoentry.dotmode % 100 == 1) ? 'B' : ' ';
  1029.    sprintf(buf,"%-5s %-25s %4d %4d %3d%c %-25s",  /* 72 chars */
  1030.        kname, videoentry.name, videoentry.xdots, videoentry.ydots,
  1031.        videoentry.colors, biosflag, videoentry.comment);
  1032. }
  1033.  
  1034. static int check_modekey(int curkey,int choice)
  1035. {
  1036.    int i,j,k,ret;
  1037.    if ((i = check_vidmode_key(1,curkey)) >= 0)
  1038.       return(-1-i);
  1039.    i = entsptr[choice];
  1040.    ret = 0;
  1041.    if ( (curkey == '-' || curkey == '+')
  1042.      && (vidtbl[i].keynum == 0 || vidtbl[i].keynum >= 1084)) {
  1043.       static char far msg[]={"Missing or bad FRACTINT.CFG file. Can't reassign keys."};
  1044.       if (badconfig)
  1045.      stopmsg(0,msg);
  1046.       else {
  1047.      if (curkey == '-') {                   /* deassign key? */
  1048.         if (vidtbl[i].keynum >= 1084) {
  1049.            vidtbl[i].keynum = 0;
  1050.            modes_changed = 1;
  1051.            }
  1052.         }
  1053.      else {                 /* assign key? */
  1054.         j = getakeynohelp();
  1055.         if (j >= 1084 && j <= 1113) {
  1056.            for (k = 0; k < vidtbllen; ++k) {
  1057.           if (vidtbl[k].keynum == j) {
  1058.              vidtbl[k].keynum = 0;
  1059.              ret = -1; /* force redisplay */
  1060.              }
  1061.           }
  1062.            vidtbl[i].keynum = j;
  1063.            modes_changed = 1;
  1064.            }
  1065.         }
  1066.      }
  1067.       }
  1068.    return(ret);
  1069. }
  1070.  
  1071. static int entcompare(void const *p1,void const *p2)
  1072. {
  1073.    int i,j;
  1074.    if ((i = vidtbl[*((int *)p1)].keynum) == 0) i = 9999;
  1075.    if ((j = vidtbl[*((int *)p2)].keynum) == 0) j = 9999;
  1076.    if (i < j || (i == j && *((int *)p1) < *((int *)p2)))
  1077.       return(-1);
  1078.    return(1);
  1079. }
  1080.  
  1081. static void update_fractint_cfg()
  1082. {
  1083.    char cfgname[100],outname[100],buf[121],kname[5];
  1084.    FILE *cfgfile,*outfile;
  1085.    int far *cfglinenums;
  1086.    int i,j,linenum,nextlinenum,nextmode;
  1087.    struct videoinfo vident;
  1088.  
  1089.    findpath("fractint.cfg",cfgname);
  1090.    if (access(cfgname,6)) {
  1091.       sprintf(buf,s_cantwrite,cfgname);
  1092.       stopmsg(0,buf);
  1093.       return;
  1094.       }
  1095.    strcpy(outname,cfgname);
  1096.    i = strlen(outname);
  1097.    while (--i >= 0 && outname[i] != '\\')
  1098.    outname[i] = 0;
  1099.    strcat(outname,"fractint.tmp");
  1100.    if ((outfile = fopen(outname,"w")) == NULL) {
  1101.       sprintf(buf,s_cantcreate,outname);
  1102.       stopmsg(0,buf);
  1103.       return;
  1104.       }
  1105.    cfgfile = fopen(cfgname,"r");
  1106.  
  1107.    cfglinenums = (int far *)(&vidtbl[MAXVIDEOMODES]);
  1108.    linenum = nextmode = 0;
  1109.    nextlinenum = cfglinenums[0];
  1110.    while (fgets(buf,120,cfgfile)) {
  1111.       ++linenum;
  1112.       if (linenum == nextlinenum) { /* replace this line */
  1113.      far_memcpy((char far *)&vident,(char far *)&vidtbl[nextmode],
  1114.             sizeof(videoentry));
  1115.      vidmode_keyname(vident.keynum,kname);
  1116.      strcpy(buf,vident.name);
  1117.      i = strlen(buf);
  1118.      while (i && buf[i-1] == ' ') /* strip trailing spaces to compress */
  1119.         --i;
  1120.      j = i + 5;
  1121.      while (j < 32) {        /* tab to column 33 */
  1122.         buf[i++] = '\t';
  1123.         j += 8;
  1124.         }
  1125.      buf[i] = 0;
  1126.      fprintf(outfile,"%-4s,%s,%4x,%4x,%4x,%4x,%4d,%4d,%4d,%3d,%s\n",
  1127.         kname,
  1128.         buf,
  1129.         vident.videomodeax,
  1130.         vident.videomodebx,
  1131.         vident.videomodecx,
  1132.         vident.videomodedx,
  1133.         vident.dotmode,
  1134.         vident.xdots,
  1135.         vident.ydots,
  1136.         vident.colors,
  1137.         vident.comment);
  1138.      if (++nextmode >= vidtbllen)
  1139.         nextlinenum = 32767;
  1140.      else
  1141.         nextlinenum = cfglinenums[nextmode];
  1142.      }
  1143.       else
  1144.      fputs(buf,outfile);
  1145.       }
  1146.  
  1147.    fclose(cfgfile);
  1148.    fclose(outfile);
  1149.    unlink(cfgname);        /* success assumed on these lines        */
  1150.    rename(outname,cfgname); /* since we checked earlier with access */
  1151. }
  1152.  
  1153.  
  1154.